package DesginFotmat;

import lombok.extern.slf4j.Slf4j;

import java.util.LinkedList;

public class MessageQueueTest {
    public static void main(String[] args) {
        MessageQueue queue = new MessageQueue(2);
        for (int i = 0; i < 3; i++) {
            int id = i;
            new Thread(()->{
                while(true) {
                    queue.put(new Message(id,"值"+id));
                }
            },"生产者"+i).start();
        }

        new Thread(()->{
            while(true){
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                Message message = queue.take();
            }
        },"消费者").start();
    }
}


@Slf4j
//消息队列类，java线程之间通信
class MessageQueue {
    //消息大的队列集合
    private LinkedList<Message> list = new LinkedList<Message>();
    //队列容量
    private int capacity;
    public MessageQueue(int capacity) {
        this.capacity = capacity;
    }

    //获取消息
    public Message take(){
        //检查队列是否为空
        synchronized (list){
            while(list.isEmpty()){
                try {
                    log.debug("队列为空，消费者线程等待");
                    list.wait();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }

            //从队列头部获取消息并返回
            Message message = list.removeFirst();
            log.debug("已消费消息{}",message);
            list.notifyAll();
            return message;
        }
    }

    //存入消息
    public void put(Message message){
        synchronized (list){
            //检查队列是否已满
            while(list.size() == capacity){
                try {
                    log.debug("队列已满，生产者线程等待");
                    list.wait();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
            //将消息加入队列尾部
            list.addLast(message);
            log.debug("已生产消息{}",message);
            list.notifyAll();
        }
    }
}

final class Message{
    private int id;
    private Object value;
    public Message(int id, Object value){
        this.id = id;
        this.value = value;
    }

    public String toString(){
        return "Message{"+
                "id="+id +
                ",value=" +
                value +
                "}";
    }
}
